﻿using Abp;
using Abp.Application.Services;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.ObjectMapping;
using Abp.Runtime.Caching;
using FwProject.Com.Dto;
using FwProject.Commodity.Dto;
using FwProject.Manager;
using FwProject.ShopApplication;
using FwProject.ShoppingMall.Com;
using FwProject.ShoppingMall.Commodity;
using FwProject.ShoppingMall.Shop;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using X.PagedList;
namespace FwProject.Com
{
    /// <summary>
    /// 商品收藏管理
    /// </summary>

    public class CommodityCollectionAppService : FwProjectAppServiceBase, ICommodityCollectionAppService
    {
        private CommodityCollectionManager _commodityCollectionManager;
        private readonly IRepository<CommodityCollection, Guid> _repositoryCommodityCollection;
        private readonly IRepository<ShopProduct, Guid> _repositoryShopProduct;
        private readonly ICacheManager _catchmanager;
        /// <summary>
        /// 
        /// </summary>
        public IGuidGenerator _guid { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public IObjectMapper _map { get; set; }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="commodityCollectionManager"></param>
        /// <param name="repositoryCommodityCollection"></param>
        /// <param name="repositoryShopProduct"></param>
        public CommodityCollectionAppService(CommodityCollectionManager commodityCollectionManager,
            IRepository<CommodityCollection, Guid> repositoryCommodityCollection,
            IRepository<ShopProduct, Guid> repositoryShopProduct, ICacheManager catchmanager)
        {
            _catchmanager = catchmanager;
            _repositoryShopProduct = repositoryShopProduct;
            _repositoryCommodityCollection = repositoryCommodityCollection;
            _commodityCollectionManager = commodityCollectionManager;
            _guid = SequentialGuidGenerator.Instance;
        }
        /// <summary>
        /// 设置收藏
        /// </summary>
        /// <param name="model">收藏模型</param>
        /// <returns>主键编号 如果没有收藏默认收藏，如果已经收藏设置为不收藏</returns>
        [AbpAuthorize]
        public async Task<Guid> SetCommodityCollection(CommodityCollectionInput model)
        {
            var m = _map.Map<CommodityCollection>(model);
            m.Id = _guid.Create();
            m.UserId = AbpSession.UserId.Value;
            return await _commodityCollectionManager.CreateCommodityCollection(m);
        }
        /// <summary>
        /// 获取我关注的产品
        /// </summary>
        /// <param name="page">页数</param>
        /// <param name="pageSize">条数</param>
        /// <returns>list返回我关注的商品信息</returns>
        [AbpAuthorize]
        public async Task<IPagedList<CommodityCollectionProductShopDto>> GetCommodityCollectionProduct(int page, int pageSize)
        {
            var list = _repositoryCommodityCollection.GetAll().Where(o => o.UserId == AbpSession.UserId && o.isActive == true).OrderByDescending(o => o.CreationTime);
            var shopList = _repositoryShopProduct.GetAll().Where(o => o.IsGrounding == true);
            return await list.Join(shopList, t => t.ShopproductId, k => k.Id, (o, m) => new CommodityCollectionProductShopDto
            {
                Id = o.Id,
                UserId = o.UserId,
                ShopproductId = o.ShopproductId,
                ShopTypeid = m.ShopTypeid,
                ProductName = m.ProductName,
                SpcemarketPrice = m.MarketPrice,
                IsGrounding = m.IsGrounding,
                Unit = m.Unit,
                ImagePic = m.ImagePic,
                SpceWeight = m.SpceWeight,
                CommodityCollectionCount = GetCache.Where(t => t.ShopproductId == o.ShopproductId).Count()
            }).ToPagedListAsync(page, pageSize);
        }

        /// <summary>
        /// 通过商品id判断是否收藏过此商品
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>

        public async Task<bool> GetCommodityCollection(Guid shopid)
        {

            if (!AbpSession.UserId.HasValue)
                return false;

            var t = await _repositoryCommodityCollection.GetAllListAsync();
            var m = t.Where(o => o.UserId == AbpSession.UserId.Value && o.ShopproductId == shopid && o.isActive == true).FirstOrDefault();
            if (m == null)
                return false;

            return true;
        }

        /// <summary>
        /// 删除收藏
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [AbpAuthorize]
        public async Task DeleteCommodityCollection(Guid id)
        {
            var model = _repositoryCommodityCollection.Get(id);
            await _commodityCollectionManager.DeleteCommodityCollection(model);
        }

        #region 后台管理
        /// <summary>
        /// 获取商品收藏统计
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public async Task<LayerDataBaseDto> GetShopCollectionAsync(int page, int limit)
        {
            var entity = await _repositoryCommodityCollection.GetAll().GroupBy(o => o.ShopproductId).Select(s => new
            {
                ShopProductId = s.Key,
                CollectionCount = s.Count()
            }).Join(_repositoryShopProduct.GetAll(),a=>a.ShopProductId,b=>b.Id,(a,b)=>new {
                b.ProductName,
                b.MarketPrice,
                a.CollectionCount
            }).OrderByDescending(o=>o.CollectionCount).Take(10).ToPagedListAsync(page,limit);

            LayerDataBaseDto dto = new LayerDataBaseDto();
            dto.Data = entity;
            dto.Count = entity.TotalItemCount;
            return dto;
        }

        public async Task<List<CollectionCountDto>> GetCollectionCountAsync()
        {
            var entity = await _repositoryCommodityCollection.GetAll().GroupBy(o => o.ShopproductId).Select(s => new
            {
                ShopProductId = s.Key,
                CollectionCount = s.Count()
            }).Join(_repositoryShopProduct.GetAll(), a => a.ShopProductId, b => b.Id, (a, b) => new CollectionCountDto
            {
               ProductName= b.ProductName,
                CollectionCount = a.CollectionCount
            }).OrderByDescending(o => o.CollectionCount).Take(10).ToListAsync();

            return entity;
        }

        #endregion

        private List<CommodityCollection> GetCache
        {
            get
            {
                ICache cache = _catchmanager.GetCache(nameof(CommodityCollection));
                return cache.Get("list", () => _repositoryCommodityCollection.GetAll().Where(o => o.isActive == true).ToList());
            }

        }
    }
}
